package com.example.gobang.controller;
import com.example.gobang.game.*;
import com.example.gobang.mapper.UserMapper;
import com.example.gobang.model.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;

@Component
public class GameController extends TextWebSocketHandler {
    @Autowired
    OnlineUserManager onlineUserManager;
    @Autowired
    ObjectMapper objectMapper;
    @Autowired
    RoomManager roomManager;
    @Autowired
    UserMapper userMapper;
ObjectMapper mapper = new ObjectMapper();
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        User user = (User) session.getAttributes().get("user");
        GameReadyResponse  gameReadyResponse = new GameReadyResponse();

        if (user == null) {
           gameReadyResponse.setReason("用户未登录！");
           gameReadyResponse.setOk(false);
           session.sendMessage(new TextMessage(gameReadyResponse.toString()));
           return;
        }

        if(onlineUserManager.getFromGameHall(user.getUserId()) != null||
                onlineUserManager.getFromGameRoom(user.getUserId()) != null) {
            gameReadyResponse.setReason("重复登录！");
            gameReadyResponse.setOk(true);
            gameReadyResponse.setMessage("repeatConnection");
            session.sendMessage(new TextMessage(gameReadyResponse.toString()));
            return;
        }

        Room room = roomManager.getRoomByUserId(user.getUserId());
        if(room == null) {
            gameReadyResponse.setReason("未匹配到房间！");
            gameReadyResponse.setOk(false);
            session.sendMessage(new TextMessage(gameReadyResponse.toString()));
            return;
        }

        onlineUserManager.enterGameRoom(user.getUserId(),session);
        synchronized (room){
            if(room.getUser1()==null){
                room.setUser1(user);
                room.setWhiteUser(user.getUserId());
                System.out.println("用户1 "+user.getUsername()+"已经准备就绪！");
                return;
            }
            if(room.getUser2()==null){
                room.setUser2(user);
                System.out.println("用户2 "+user.getUsername()+"已经准备就绪！");
                noticeGameReady(room,room.getUser1(),room.getUser2());
                noticeGameReady(room,room.getUser2(),room.getUser1());
                return;
            }
        }
        gameReadyResponse.setOk(false);
        gameReadyResponse.setReason("当前房间已满！");
        session.sendMessage(new TextMessage(gameReadyResponse.toString()));
    }

    private void noticeGameReady(Room room, User user1, User user2) throws IOException {
        GameReadyResponse gameReadyResponse = new GameReadyResponse();
        gameReadyResponse.setOk(true);
        gameReadyResponse.setMessage("gameReady");
        gameReadyResponse.setReason("");
        gameReadyResponse.setWhiteUser(room.getWhiteUser());
        gameReadyResponse.setThisUserId(user1.getUserId());
        gameReadyResponse.setThatUserId(user2.getUserId());
        gameReadyResponse.setRoomId(room.getRoomId());
        WebSocketSession wsSession = onlineUserManager.getFromGameRoom(user1.getUserId());
        if(wsSession==null){
            gameReadyResponse.setOk(false);
            return;
        }
        wsSession.sendMessage(new TextMessage(objectMapper.writeValueAsString(gameReadyResponse)));

    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if(user==null){
            System.out.println("用户未登录！");
            return;
        }
        Room room = roomManager.getRoomByUserId(user.getUserId());
        if(room==null){
            System.out.println("用户"+user.getUsername()+"的房间不存在！");
            return;
        }


        String text = message.getPayload();
        //System.out.println("收到消息："+text);
        BackMoveResponse backMoveResponse = new BackMoveResponse();
        if(text.contains("backMove")){
            BackMoveRequest backMoveRequest = mapper.readValue(text, BackMoveRequest.class);
            //System.out.println("悔棋请求信息"+backMoveRequest);
            if(room.backMove()){
                backMoveResponse.setOk(true);
                backMoveResponse.setMessage("backMoveSuccess");
                //通知对方
                User thatUser = user==room.getUser1()?room.getUser2():room.getUser1();
                WebSocketSession thatSession = onlineUserManager.getFromGameRoom(thatUser.getUserId());
                if(thatSession!=null){
                    thatSession.sendMessage(new TextMessage(objectMapper.writeValueAsString(backMoveResponse)));
                }
            }else{
                backMoveResponse.setOk(false);
                backMoveResponse.setReason("无法悔棋！");
            }
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(backMoveResponse)));
        }else
            room.putChess(message.getPayload());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
      User user = (User) session.getAttributes().get("user");
      if(user==null){
          return;
      }
      WebSocketSession wsSession = onlineUserManager.getFromGameRoom(user.getUserId());
      if(wsSession==session){
          System.out.println("多开了");
          onlineUserManager.exitGameRoom(user.getUserId());
      }
        noticeThatUserWin(user);
    }

    private void noticeThatUserWin(User user) {
        Room room = roomManager.getRoomByUserId(user.getUserId());
        if(room==null){
            return;
        }
        User thatUser = user==room.getUser1()?room.getUser2():room.getUser1();
        WebSocketSession wsSession = onlineUserManager.getFromGameHall(thatUser.getUserId());
        if(wsSession==null){
            //双方都掉线
            return;
        }
        GameResponse gameReadyResponse = new GameResponse();
        gameReadyResponse.setWinner(thatUser.getUserId());
        gameReadyResponse.setMessage("putChess");
        gameReadyResponse.setUserId(thatUser.getUserId());
        WebSocketSession wsSession2 = onlineUserManager.getFromGameHall(thatUser.getUserId());
        userMapper.userWin(thatUser.getUserId());
        userMapper.userLose(thatUser.getUserId());
        roomManager.remove(room.getRoomId(),room.getUser1().getUserId(),room.getUser2().getUserId());
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if(user==null){
            return;
        }
        WebSocketSession wsSession = onlineUserManager.getFromGameHall(user.getUserId());
        if(wsSession==session){
            System.out.println("多开了");
            onlineUserManager.exitGameRoom(user.getUserId());
        }
        System.out.println("当前用户"+user.getUsername()+"游戏房间连接异常！");
        //在异常情况下判断对手获胜
        noticeThatUserWin(user);
    }
}